#include "MT6701.h"
#include "wk_spi.h"
#include "wk_system.h"

uint8_t MT6701_init(void)
{
  wk_spi2_init();
  return 0;
}

/**
 * @brief 读取MT6701角度传感器的数据通过SPI接口
 *
 * 该函数通过SPI接口与MT6701角度传感器通信，以读取传感器检测到的角度值
 * 它首先等待SPI接口准备好，然后发送一个请求信号给传感器，
 * 并在接收到传感器返回的数据后进行处理，最后返回角度值
 *
 * @param angle_raw 存储角度值的变量
 * @return 0 表示成功，非 0 表示失败
 */
uint8_t MT6701_ReadAngleSPI(uint16_t *angle_raw)
{
  // 等待SPI接口数据发送缓冲区空
  while (spi_i2s_flag_get(SPI2, SPI_I2S_TDBE_FLAG) == RESET)
    ;

  // 拉低SPI芯片选择线，准备与MT6701通信
  gpio_bits_reset(GPIOB, GPIO_PINS_12);

  // 发送一个全1的数据给MT6701，作为读取角度数据的请求
  spi_i2s_data_transmit(SPI2, 0xffff);

  // 等待SPI接口数据接收缓冲区满
  while (spi_i2s_flag_get(SPI2, SPI_I2S_RDBF_FLAG) == RESET)
    ;

  // 接收从MT6701返回的角度数据，并进行右移两位处理
  *angle_raw = spi_i2s_data_receive(SPI2) >> 2; // 初始化直接是读16个字节

  // 等待SPI接口忙标志位清零
  while (spi_i2s_flag_get(SPI2, SPI_I2S_BF_FLAG) == SET)
    ;

  // 拉高SPI芯片选择线，结束与MT6701的通信
  gpio_bits_set(GPIOB, GPIO_PINS_12);

  // 返回接收到的原始角度数据
  return 0;
}

/**
 * @brief 从MT6701传感器获取角度信息
 *
 * @param angle_raw 指向存储原始角度数据的指针，数据类型为uint16_t
 * @param angle_f 指向存储转换后的浮点数角度的指针，数据类型为float
 * @return uint8_t 返回错误代码，
 *         0 表示成功
 *         1 表示 angle_f 为 NULL
 *         2 表示 SPI 读取失败
 */
uint8_t MT6701_get_angle(uint16_t *angle_raw, float *angle_f)
{
  uint8_t res;
  uint16_t angle_raw_temp;

  if (angle_f == NULL)
    return 1;

  // 如果 angle_raw 为 NULL，则使用 angle_raw_temp 存储原始角度数据
  if (angle_raw == NULL)
    angle_raw = &angle_raw_temp;

  // 读取原始角度数据
  res = MT6701_ReadAngleSPI(angle_raw);
  if (0 != res)
  {
    // 如果读取失败，直接返回错误代码
    return 2;
  }

  // 单位化：将原始角度数据转换为浮点数表示的角度
  *angle_f = (float)(*angle_raw) / (float)COUNT_PER_ROTATE * _2PI;
  // 返回成功代码
  return 0;
}
